#ifndef __NOOS_PSM
#define __NOOS_PSM


class Prediction {
public:
	Prediction(FeatureTerm *p);
	~Prediction();

	void print(FTKBase *dm) {
		int i;

		printf("Prediction: number of possible solutions (%i): ----------------------\n",solutions.Length());
		for(i=0;i<solutions.Length();i++) { 
			char *s1,*s2;
			FeatureTerm *solution = solutions[i];
			FeatureTerm *justification = justifications[i];
			s1 = solution->toStringNOOS(dm);
			s2 = justification->toStringNOOS(dm);
			printf("- Justification for %s (support:%i)\n%s\n",s1,*(support[i]),s2);
			delete []s1;
			delete []s2;
		} // while  		
	}


	float getScore(FeatureTerm *realSolution) {
		float total = 0,correct = 0;
		int i;
		for(i=0;i<solutions.Length();i++) { 
			FeatureTerm *solution = solutions[i];
			if (realSolution->equivalents(solution)) correct+=*(support[i]);
			total+=*(support[i]);
		}
		
		if (total>0) return correct/total;
		return 1.0f/(float)solutions.Length();
	}


	FeatureTerm *problem;
	List<FeatureTerm> justifications;
	List<FeatureTerm> solutions;
	List<int> support;
};


class Hypothesis {
public:

	Hypothesis();
	Hypothesis(Hypothesis *h);
	~Hypothesis();

	FeatureTerm *solve_problem(FeatureTerm *problem,FTKBase *domain_model);	
	Prediction *generate_prediction(FeatureTerm *problem,FTKBase *domain_model);	
	void show_rule_set(FTKBase *domain_model);		// uses printf
	void report_rule_set(FTKBase *domain_model);	// uses "write_debug_report"

	
	List<FeatureTerm> m_patterns;
	List<FeatureTerm> m_solutions;
	List<float> m_reliability;
	List<bool> m_positive_coverage;		/* contains a vector with a boolean per each positive example, saying if the 
										   pattern subsumes that example or not	*/ 
	FeatureTerm *m_default_solution;
};


FeatureTerm *refinement_LID(FeatureTerm *problem,List<FeatureTerm> *cases,Path *description_path,Path *solution_path,Ontology *o,FTKBase *domain_model,int heuristic,int selection_mode,int min_precedents);
FeatureTerm *refinement_LID2(FeatureTerm *problem,List<FeatureTerm> *cases,Path *description_path,Path *solution_path,Ontology *o,FTKBase *domain_model,int heuristic,int selection_mode,int min_precedents);
Prediction *refinement_LID3(FeatureTerm *problem,List<FeatureTerm> *cases,Path *description_path,Path *solution_path,Ontology *o,FTKBase *domain_model,int heuristic,int selection_mode,int min_precedents);
Prediction *eva_LID(FeatureTerm *problem,List<FeatureTerm> *cases,Path *description_path,Path *solution_path,Ontology *o,FTKBase *domain_model,int heuristic,int selection_mode,int min_precedents);
Prediction *unification_eva_LID(FeatureTerm *problem,List<FeatureTerm> *cases,Path *description_path,Path *solution_path,Ontology *o,FTKBase *domain_model,int heuristic,int selection_mode,int min_precedents);

#endif

